iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
Modern Web

NestJs 讀書筆記系列 第 8

在 NestJs 如何使用 MongoDB

  • 分享至 

  • xImage
  •  

MongoDB (Mongoose)

目標:

  1. 透過 GraphQL Playground 操作 MongoDB CRUD

前幾篇的介紹中,已經有介紹過 MySQL ,有興趣的讀者可以點閱。
這篇章看標題就知道要介紹如何在 NestJs 中使用 MongoDB

執行 MongoDB

實作過程中,我沒有在本機直接安裝 MongoDB,而是在 Docker 中運行一個 MongoDB

這邊提供簡單的範例

  1. 在根目錄下新增 docker-compose.yml
  2. 將範例複製貼上

    docker-compose.yml

    version: "3.7"
    
    services:
      mongodb:
        image: mongo:4.2
        environment:
          MONGO_INITDB_ROOT_USERNAME: root
          MONGO_INITDB_ROOT_PASSWORD: test
        ports:
          - 27017:27017
        volumes:
          - mongodb_data:/data/db
    volumes:
      mongodb_data:
    
  3. 在終端機執行 docker-compose up
  4. 在終端機開一個新視窗,執行 docker ps,檢查是否啟動成功
    CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                    PORTS                               NAMES
    d75ea2bd8fa8        mongo:4.2                  "docker-entrypoint.s…"   2 days ago          Exited (0) 46 hours ago                                       tutorial-graphql_mongodb_1
    

MongoDB Compass

首先先下載 MongoDB 提供的 GUI MongoDB Compass ,我們可以透過這個工具來觀察資料的數據,也能直接對資料庫做 CRUD,我覺得還蠻好用的,所以推薦讀者使用。

如果已經有其他習慣的工具,也不強迫使用 MongoDB Compass,依照個人喜好做決定。

  1. 先建立一個新的 Connection,根據設定輸入mongodb://username:password@host:port/database 按下 CONNECT

  1. 連線成功後可以看到類似的畫面,下圖是我建立了一個 cats Collection ,已經成功寫入兩筆資料。
    MongoDB Compass 還提供很多功能,但這邊就不一一解釋,後續有用到會再慢慢說明,如果讀者有問題也可以在留言區提出。

完成這些步驟就完成 MongoDB 建置,也有 GUI 可以隨時觀看資料庫狀況,接下來就開始將實作應用程式與資料庫的對接!

回到 NestJs

  1. 首先先安裝 mongoose,它是一個給 NodeJs 使用的 MongoDB ODM
yarn add mongoose @types/mongoose
  1. 建立與資料庫的 connection ,使用 mongoose 提供的 connect 函式,填入所需的資訊
    mongoose.connect('mongodb://username:password@host:port/database?options...', {useNewUrlParser: true});

    根據 NestJs 官網所給的範例就會像這樣

// 目錄:src/database/database.providers.ts

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://root:test@localhost:27017/admin'),
  },
];
  1. 將 database provider export,讓需要使用的模組可以直接 import
// 目錄:src/database/database.module.ts

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
  1. 定義 DB collection 的 Schema ,使用 mongoose 提供的方法撰寫 Cats 的 Schema
// 目錄:src/cats/schemas/cats.schema.ts

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
    name: String,
    age: Number,
    color: String
});
  1. 建立一個 Model provider
// 目錄: src/cats/cats.providers.ts

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cats.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
  1. 接下來 import 剛剛建立的 DatabaseModule 以及 catsProviders
    • catsProviders 引入到 cats 的 providers,其他模組就能使用定義好的 CAT_MODEL 使用 CatSchema
// 目錄:src/cats/cats.module.ts

import { Module } from '@nestjs/common';
import { CatsService } from './cats.service';
import { CatResolver } from './cats.resolver';
import { DatabaseModule } from '../database/database.module';
import { catsProviders } from './cats.providers';

@Module({
    imports: [DatabaseModule],
    providers: [CatsService, CatResolver, ...catsProviders],
})
export class CatsModule {}
  1. 最後將 CAT_MODEL 用裝飾器 @Inject 注入到 CatsService ,使用 mongoose 提供的 ORM 將資料做寫入以及搜尋出需要的資料

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { CatInput } from '../graphql.schema'
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
    constructor(
        @Inject('CAT_MODEL')
        private catModel: Model<Cat>,
    ) {}

    async create(cat: CatInput): Promise<Cat> {
        // 把 cat 寫入 cats collection
        const createdCat = new this.catModel(cat);

        return createdCat.save();
    }

    async findAll(): Promise<Cat[]> {
        // 搜尋 cats collection 所有資料
        const cats = await this.catModel.find().exec();

        return cats
    }
}

操作 Playground

將服務啟動後,在瀏覽器輸入 http://localhost:3000/graphql
執行 Mutation 將資料寫入資料庫,回傳成功後可以打開 MongoDB Compass
admin 裡可以看到多一個 cats 的 collection ,點擊進去就能看到剛剛所 create 資料

在執行 Query ,就能將 cats collection 資料全部撈出來顯示

以上就是這章節的內容,如有問題請在留言處發問,最後請訂閱案小鈴鐺


上一篇
如何在 NestJs 中運行 GraphQL
下一篇
NestJs - GraphQL 內部結構說明 (上篇)
系列文
NestJs 讀書筆記31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言